﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;

namespace EnterpriseFramework.DataAccess
{
    public class Query
    {
        private Dictionary<string, object> dic = new Dictionary<string, object>();
        private QueryResult qResult = null;

        internal QueryResult QResult
        {
            get { return qResult; }
        }

        public Query()
        {
            qResult = new QueryResult();
        }

        public Query Columns(params string[] ColumnsExpression)
        {
            if (ColumnsExpression.Length > 0)
                qResult.ColumnExpression = string.Join(",", ColumnsExpression);

            return this;
        }

        public Query Where(Where WhereClause)
        {

            if (qResult.WhereClause == null)
            {
                SearchCriteria sc = new SearchCriteria();
                sc.Criteria = WhereClause.Expression;
                sc.Parameters = WhereClause.ParamList.ToArray();
                qResult.WhereClause = sc;
            }
            else
            {
                qResult.WhereClause.Criteria = WhereClause.Expression;
                qResult.WhereClause.Parameters = WhereClause.ParamList.ToArray();
            }

            //<e> 1
            return this;
        }

        public Query Having(Where HavingClause)
        {

            if (qResult.WhereClause == null)
            {
                SearchCriteria sc = new SearchCriteria();
                sc.Criteria = HavingClause.Expression;
                sc.Parameters = HavingClause.ParamList.ToArray();
                qResult.HavingClause = sc;
            }
            else
            {
                qResult.HavingClause.Criteria = HavingClause.Expression;
                qResult.HavingClause.Parameters = HavingClause.ParamList.ToArray();
            }

            //<e> 1
            return this;
        }
                
        public Query OrderBy(params string[] OrderColumns)
        {
            //if (!dic.ContainsKey("OrderBy"))
            //    dic.Add("OrderBy", OrderByExpression);
            if (OrderColumns.Length > 0)
                qResult.OrderBy = string.Join(",", OrderColumns);
            //<e> 1
            return this;
        }

        public Query GroupBy(params string[] Items)
        {
            if (Items.Length > 0)
                qResult.GroupBy = string.Join(",", Items);
            //<e> 1
            return this;
        }

        public Query Top(int NumOfRow)
        {
            qResult.Top = NumOfRow;
            //<e> 1
            return this;
        }

        public Query Distinct
        {
            get
            {
                qResult.Distinct = "DISTINCT";
                return this;
            }
        }
        
        public Query InnerJoin(BaseEntity Table1, BaseEntity Table2, string Condition)
        {
            qResult.InnerJoin.Add(new Join(Table1.GetType().Name, Table2.GetType().Name, Condition));
            //<e> 1
            return this;
        }

        public Query LeftJoin(BaseEntity Table1, BaseEntity Table2, string Condition)
        {
            qResult.LeftJoin.Add(new Join(Table1.GetType().Name, Table2.GetType().Name, Condition));
            //<e> 1
            return this;
        }

        public Query RightJoin(BaseEntity Table1, BaseEntity Table2, string Condition)
        {
            qResult.RightJoin.Add(new Join(Table1.GetType().Name, Table2.GetType().Name, Condition));
            //<e> 1
            return this;
        }

        public Query FullJoin(BaseEntity Table1, BaseEntity Table2, string Condition)
        {
            qResult.FullJoin.Add(new Join(Table1.GetType().Name, Table2.GetType().Name, Condition));
            //<e> 1
            return this;
        }

        public Query CrossJoin(BaseEntity Table1, BaseEntity Table2)
        {
            qResult.FullJoin.Add(new Join(Table1.GetType().Name, Table2.GetType().Name, string.Empty));
            //<e> 1
            return this;
        }

        private string ModifyParam(string con, string crit, ref List<Parameter> parmList)
        {
            StringBuilder _crit = new StringBuilder().Append(crit);
            string pattern = @"(@)";
            int y = 0;
            int count = 0;
            foreach (Match match in Regex.Matches(_crit.ToString(), pattern, RegexOptions.IgnoreCase))
            {
                _crit.Replace(match.Value, "@" + con + count.ToString());
                if (string.IsNullOrEmpty(parmList[count].ParameterName))
                    parmList[count].ParameterName = con + count.ToString();
                y++;
            }
            return _crit.ToString();
        }

        public Dictionary<string, object> ResqultQuery
        {
            get { return dic; }
        }

    }
}
